
package com.hd.sup.modules.alarm.util;

import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hd.common.constant.BizConstant;
import com.hd.common.utils.CollectionUtils;
import com.hd.common.utils.DateUtil;
import com.hd.common.utils.Pair;
import com.hd.common.utils.ValueUtils;
import com.hd.sup.modules.alarm.model.AlarmRule;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.MessageFormat;
import java.util.*;


/**
 * @author chentl
 * @version V1.0
 * @Project 交通运输第三方监测平台
 * @Title TemplateUtils.java
 * @Description 模板工具类
 * @Package com.hd.sup.modules.alarm.util
 * @date 2021/1/6 6:02 下午
 * @Copyright: 深圳市宏电技术股份有限公司 All rights reserved.
 */
@Slf4j
public class TemplateUtils {

    /**
     * @Description 报警趋势波动因子
     * @Author chentl
     * @Create: 2021/2/18 5:17 下午
     */
    final static int fluctuationFactor = 100;


    /**
     * @return java.lang.String
     * @author chentl
     * @description 分析报告总结
     * @date 2021/2/20 3:19 下午
     * @params [all, timeFlag]
     */
    public static String getAlarmSummary(Map<String, Object> all, String timeFlag) {
        String desc = "";
        try {


            JSONObject jsonNode = (JSONObject) JSONObject.toJSON(all);
            JSONObject alarm_data = (JSONObject) ((JSONObject) ((JSONObject) jsonNode.get("all_alarm")).get("alarm_distribution")).get("data");
            JSONArray enterprise_ratio_data = (JSONArray) ((JSONObject) ((JSONObject) jsonNode.get("all_alarm")).get("enterprise_ratio_data")).get("data");
            JSONArray vehicle_ratio_data = (JSONArray) ((JSONObject) ((JSONObject) jsonNode.get("all_alarm")).get("vehicle_ratio_data")).get("data");

            if (alarm_data.size() == 0 || enterprise_ratio_data.size() == 0 || vehicle_ratio_data.size() == 0)
                return "";

            String ere_name = ValueUtils.parseString(((JSONObject) enterprise_ratio_data.get(0)).get("enterprise_name"));
            String vre_name = ValueUtils.parseString(((JSONObject) vehicle_ratio_data.get(0)).get("enterprise_name"));
            String vre_plat_no = ValueUtils.parseString(((JSONObject) vehicle_ratio_data.get(0)).get("plat_no"));
            String vre_alarm_sum = ValueUtils.parseString(((JSONObject) vehicle_ratio_data.get(0)).get("alarm_sum"));
            Integer alarm_sum = ValueUtils.parseInteger(alarm_data.get("alarmSum"));
            Pair<String, Integer> maxAlarm = getMaxAlarm(alarm_data);
            String maxProportion = ValueUtils.getRate(maxAlarm.second, alarm_sum, 2);
            String maxAlarmName = BizConstant.AlarmType.getLike(maxAlarm.first).val();


            if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
                desc = MessageFormat.format("通过对两客一危车辆动态信息的统计分析，发现如下突出问题：" +
                        "一是车辆总报警共计{0}次， 其中{1}最为严重，占到总报警次数的{2}% ， " +
                        "建议管理部门加强检查，开展专项整治措施，督促企业认真落实动态监控主体责任， 贯彻动态监控相关要求，降低{1}总次数，将造成事故的可能性降到最低； " +
                        "二是今日在我市所有两客一危企业中，{3}车辆报警情况最为严重， 需管理部门对企业进行通报批评并作出相应的处罚； " +
                        "三是{4}的{5}今日报警共计{6}次，在我市所有营运车辆中情况最为严重，建议对该车辆驾驶员进行通报批评及相应处罚。", alarm_sum, maxAlarmName, maxProportion, ere_name, vre_name, vre_plat_no, vre_alarm_sum);

            } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
                desc = MessageFormat.format("通过对两客一危车辆动态信息的统计分析，发现如下突出问题：" +
                        "一是车辆总报警共计{0}次， 其中{1}最为严重，占到总报警次数的{2}% ， " +
                        "建议管理部门加强检查，开展专项整治措施，督促企业认真落实动态监控主体责任， 贯彻动态监控相关要求，降低{1}总次数，将造成事故的可能性降到最低； " +
                        "二是本周在我市所有两客一危企业中，{3}车辆报警情况最为严重， 需管理部门对企业进行通报批评并作出相应的处罚； " +
                        "三是{4}的{5}本周报警共计{6}次，在我市所有营运车辆中情况最为严重，建议对该车辆驾驶员进行通报批评及相应处罚。", alarm_sum, maxAlarmName, maxProportion, ere_name, vre_name, vre_plat_no, vre_alarm_sum);

            } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
                desc = MessageFormat.format("通过对两客一危车辆动态信息的统计分析，发现如下突出问题：" +
                        "一是车辆总报警共计{0}次， 其中{1}最为严重，占到总报警次数的{2}% ， " +
                        "建议管理部门加强检查，开展专项整治措施，督促企业认真落实动态监控主体责任， 贯彻动态监控相关要求，降低{1}总次数，将造成事故的可能性降到最低； " +
                        "二是本月在我市所有两客一危企业中，{3}车辆报警情况最为严重， 需管理部门对企业进行通报批评并作出相应的处罚； " +
                        "三是{4}的{5}本月报警共计{6}次，在我市所有营运车辆中情况最为严重，建议对该车辆驾驶员进行通报批评及相应处罚。", alarm_sum, maxAlarmName, maxProportion, ere_name, vre_name, vre_plat_no, vre_alarm_sum);

            } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
                desc = MessageFormat.format("通过对两客一危车辆动态信息的统计分析，发现如下突出问题：" +
                        "一是车辆总报警共计{0}次， 其中{1}最为严重，占到总报警次数的{2}% ， " +
                        "建议管理部门加强检查，开展专项整治措施，督促企业认真落实动态监控主体责任， 贯彻动态监控相关要求，降低{1}总次数，将造成事故的可能性降到最低； " +
                        "二是今年在我市所有两客一危企业中，{3}车辆报警情况最为严重， 需管理部门对企业进行通报批评并作出相应的处罚； " +
                        "三是{4}的{5}今年报警共计{6}次，在我市所有营运车辆中情况最为严重，建议对该车辆驾驶员进行通报批评及相应处罚。", alarm_sum, maxAlarmName, maxProportion, ere_name, vre_name, vre_plat_no, vre_alarm_sum);

            }

            return desc;
        } catch (Exception e) {
            log.error("生成分析报告总结模板时发生异常", e);
            return "生成分析报告总结模板时发生异常";
        }
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 生成报警趋势描述信息
     * @date 2021/2/18 2:45 下午
     * @params [finalTrendData, timeFlag, args]
     */
    public static String getAlarmTrendDesc(LinkedHashMap<String, Object> finalTrendData, String timeFlag) {
        if (MapUtil.isEmpty(finalTrendData)) return "无趋势数据";

        String desc;
        String startSequence = "";
        if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            startSequence = "根据近六周以来的报警折线图数据,";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            startSequence = "根据近六个月以来的报警折线图数据,";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            startSequence = "根据近六年以来的报警折线图数据,";
        }

        desc = MessageFormat.format(startSequence +
                        "疲劳驾驶报警处于 {0} 趋势;" +
                        "夜间禁行报警处于 {1} 趋势;" +
                        "无数据报警处于 {2} 趋势;" +
                        "不定位报警处于 {3} 趋势。",
                computedTrendDesc(finalTrendData, BizConstant.AlarmType.FATIGUE_DRIVE.key()),
                computedTrendDesc(finalTrendData, BizConstant.AlarmType.NIGHT_NO_ENTRY.key()),
                computedTrendDesc(finalTrendData, BizConstant.AlarmType.OFF_LINE.key()),
                computedTrendDesc(finalTrendData, BizConstant.AlarmType.OFF_GPS.key()));

        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 计算趋势上升、平稳、下降
     * @date 2021/2/18 5:07 下午
     * @params []
     */
    private static String computedTrendDesc(LinkedHashMap<String, Object> finalTrendData, String alarmType) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) finalTrendData.get(alarmType);
        if (CollectionUtils.isEmpty(list)) return "未知";

        Map<String, Object> alarmTail = list.get(0);
        Map<String, Object> alarmHead = list.get(list.size() - 1);

        Integer firstSum = ValueUtils.parseInt(alarmTail.get("alarm_sum"));
        Integer lastSum = ValueUtils.parseInt(alarmHead.get("alarm_sum"));
        String trendDesc = "未知";

        int compare = Math.abs(lastSum - firstSum);
        if (firstSum < lastSum && compare > fluctuationFactor) {
            trendDesc = "上升";
        } else if (compare >= 0 && compare < fluctuationFactor) {
            trendDesc = "平稳";
        } else if (firstSum > lastSum && compare > fluctuationFactor) {
            trendDesc = "下降";
        }
        return trendDesc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取分析报告报警描述模板
     * @date 2021/2/5 9:24 上午
     * @params [timeFlag, args]
     */
    public static String getAlarmStatisDesc(String paragraphs, String timeFlag, String transType, Object... args) {
        String desc = "";
        String startSquence = "";
        String vehicleTransName = BizConstant.VehicleTransType.get(transType);
        if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
            startSquence = paragraphs + "本日" + vehicleTransName + "车辆总报警次数";
        } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            startSquence = paragraphs + "本周" + vehicleTransName + "车辆总报警次数";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            startSquence = paragraphs + "本月" + vehicleTransName + "车辆总报警次数";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            startSquence = paragraphs + "本年度" + vehicleTransName + "车辆总报警次数";
        }
        desc = MessageFormat.format(startSquence + "共计{0}次,其中 " +
                "疲劳驾驶{1}条,占报警总量的{2}%;" +
                "夜间禁行{3}条,占报警总量的{4}%;" +
                "不定位{5}条,占报警总量的{6}%;" +
                "无数据{7}条,占报警总量的{8}%;" +
                "超速{9}条,占报警总量的{10}%。", args);

        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 分析报告企业处置率描述信息
     * @date 2021/2/19 3:01 下午
     * @params [startDateStr, endDateStr, timeFlag]
     */
    public static String getEnterpriseRateDesc(String timeFlag, Object... args) {
        String desc = MessageFormat.format("{0} ~ {1} 期间，" +
                "按照《车辆动态监督管理办法》要求，" +
                "执行交通违法动态信息处理率达到90%的企业有{2}家，" +
                "未能按照要求及时处理的企业有{3}家。" +
                "处理率达到90%的企业占{4}%，" +
                "处理率最低的20家企业为: （明细表中已根据企业报警处理率对所有企业进行排名）", args);
        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取企业车辆报警比描述模板1
     * @date 2021/2/19 9:44 上午
     * @params [timeFlag, args]
     */
    public static String getEnterpriseAlarmRatioDesc1(String timeFlag) {
        String desc = "";
        String startSquence = "";
        if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据单车报警比 (报警总数/报警车辆数) 今日";
        } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据单车报警比 (报警总数/报警车辆数) 本周";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据单车报警比 (报警总数/报警车辆数) 本月";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据单车报警比 (报警总数/报警车辆数) 今年";
        }
        desc = startSquence + "本市车辆报警情况最为严重的十家企业为:";
        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取企业车辆报警比描述模板2
     * @date 2021/2/19 9:46 上午
     * @params [timeFlag]
     */
    public static String getEnterpriseAlarmRatioDesc2(String timeFlag, Object... args) {
        String desc = "";
        String startSquence = "";
        if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据今日单车报警比(报警总数/报警车辆数),";
        } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据本周单车报警比(报警总数/报警车辆数),";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据本月单车报警比(报警总数/报警车辆数),";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据今年单车报警比(报警总数/报警车辆数),";
        }
        desc = MessageFormat.format(startSquence +
                " {0} " +
                "企业报警情况最为严重。", args);
        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取单车报警描述模板1
     * @date 2021/2/19 10:46 上午
     * @params [timeFlag, args]
     */
    public static String getVehicleAlarmRatioDesc1(String timeFlag, Object... args) {
        String desc = "";
        if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
            desc = "根据单车报警数今日违规情况最为严重的十辆营运车辆为:";
        } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            desc = "根据单车报警数本周违规情况最为严重的十辆营运车辆为:";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            desc = "根据单车报警数本月违规情况最为严重的十辆营运车辆为:";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            desc = "根据单车报警数今年违规情况最为严重的十辆营运车辆为:";
        }
        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取单车报警描述模板2
     * @date 2021/2/19 10:46 上午
     * @params [timeFlag, args]
     */
    public static String getVehicleAlarmRatioDesc2(String timeFlag, Object... args) {
        String desc = "";
        String startSquence = "";
        if (BizConstant.Common.DAY.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据今日单车报警数,";
        } else if (BizConstant.Common.WEEK.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据本周单车报警数,";
        } else if (BizConstant.Common.MONTH.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据本月单车报警数,";
        } else if (BizConstant.Common.YEAR.key().equalsIgnoreCase(timeFlag)) {
            startSquence = "根据今年单车报警数,";
        }
        desc = MessageFormat.format(startSquence +
                "企业: {0} 下的车辆 {1} " +
                "报警情况最为严重。", args);
        return desc;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 根据 报警类型 和 报警时长 生成报警描述模板。
     * @date 2021/1/6 6:06 下午
     * @params [alarmType, speed, duration]
     */
    public static String alarmDescTemplate(AlarmRule alarmRule, String speed, String duration, String gpsTime) {

        if (BizConstant.AlarmType.FATIGUE_DRIVE.key().equals(alarmRule.getAlarmType())) {
            Integer limit = ValueUtils.parseInteger(alarmRule.getContinuousMinute() / 60);
            if (StringUtils.isBlank(duration)) {
                return "当前连续驾驶时长超过疲劳驾驶阈值" + limit + " 小时。";
            } else {
                return "当前连续驾驶时长累计为 " + duration + "，超过疲劳驾驶阈值 " + limit + " 小时。";
            }

        } else if (BizConstant.AlarmType.OVER_SPEED.key().equals(alarmRule.getAlarmType())) {
            Integer limit = ValueUtils.parseInteger(alarmRule.getContinuousMinute() / 60);
            return "当前车辆速度为 " + speed + "km/h，超过规定速度 " + limit + " km/h。";
        } else if (BizConstant.AlarmType.NIGHT_NO_ENTRY.key().equals(alarmRule.getAlarmType())) {
            String startTimeStr = DateUtil.format(alarmRule.getStartTime(), BizConstant.Common.DATE_FORMAT_HMS.key());
            String endTimeStr = DateUtil.format(alarmRule.getEndTime(), BizConstant.Common.DATE_FORMAT_HMS.key());
            return "当前为夜间禁行时段 " + startTimeStr + "~" + endTimeStr + "，请停车休息。";
        } else if (BizConstant.AlarmType.OFF_GPS.key().equals(alarmRule.getAlarmType())) {
            return "超过" + alarmRule.getExceededMinute() + "分钟未接收到车辆定位数据。";
        } else if (BizConstant.AlarmType.OFF_LINE.key().equals(alarmRule.getAlarmType())) {
            return "超过" + alarmRule.getExceededMinute() + "分钟未接收到车辆任何数据。";
        }


        return "未找到对应模板信息";
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取段落
     * @date 2021/3/2 11:19 上午
     * @params [index]
     */
    public static String getParagraphs(Integer index) {
        if (index == null) return "(一) ";

        String paragraphs;
        switch (index) {
            case 2:
                paragraphs = "(二) ";
                break;
            case 3:
                paragraphs = "(三) ";
                break;
            case 4:
                paragraphs = "(四) ";
                break;
            case 5:
                paragraphs = "(五) ";
                break;
            default:
                paragraphs = "";
                break;
        }
        return paragraphs;
    }

    /**
     * @return java.lang.String
     * @author chentl
     * @description 获取分析报告描述
     * @date 2021/3/2 11:47 上午
     * @params [timeFlag]
     */
    public static String getReportNameRangeDesc(String timeFlag) {
        if (StringUtils.isBlank(timeFlag)) return "";

        return "(" + BizConstant.Common.get(timeFlag) + "报)";
    }

    /**
     * @return com.hd.sup.core.utils.Pair<java.lang.Integer, java.lang.String>
     * @author chentl
     * @description 取出最大报警数 和 名称
     * @date 2021/2/19 4:26 下午
     * @params [a, b, c, d]
     */
    private static Pair<String, Integer> getMaxAlarm(JSONObject alarm_data) {
        Set<String> keySet = alarm_data.keySet();
        String maxKey = "";
        int temp = 0;
        for (String i : keySet) {
            //不计算报警总数
            if (i.equals("alarmSum")) continue;
            int a = (int) alarm_data.get(i);
            if (a >= temp) {
                maxKey = i;
                temp = a;
            }
        }

        if (StringUtils.isBlank(maxKey)) maxKey = "off_gps_sum";
        return Pair.makePair(maxKey, (Integer) alarm_data.get(maxKey));
    }


}
